﻿using System;
using System.Collections;
using System.Configuration;
using System.Data;
using System.IO;
using System.Reflection;
using System.Web.Compilation;
using Cms.Utilities;
using NHibernate;
using Configuration = NHibernate.Cfg.Configuration;
using Environment = NHibernate.Cfg.Environment;

namespace Cms.Data.ORM
{
    public class NHibernateSessionFactory
    {
        private static readonly ISessionFactory _sessionFactory;
        
        static NHibernateSessionFactory()
        {
            _sessionFactory = Configure().BuildSessionFactory();
        }

        public static Configuration Configuration
        {
            get { return Configure(); }
        }
        
        public static ISession OpenSession()
        {
            return _sessionFactory.OpenSession();
        }
        
        public static ISession OpenSession(IDbConnection connection)
        {
            return _sessionFactory.OpenSession(connection);
        }
        
        public static ISession OpenSession(AuditLogInterceptor interceptor)
        {
            return _sessionFactory.OpenSession(interceptor);
        }

        private static Configuration Configure()
        {
            var cfg = new Configuration();
            cfg.Properties.Add(Environment.ConnectionString, ConfigurationManager.ConnectionStrings["Fredium"].ConnectionString);
            cfg.Properties.Add(Environment.ConnectionProvider, "NHibernate.Connection.DriverConnectionProvider");
            cfg.Properties.Add(Environment.CommandTimeout, "120");
            cfg.Properties.Add(Environment.ProxyFactoryFactoryClass, "NHibernate.ByteCode.Castle.ProxyFactoryFactory, NHibernate.ByteCode.Castle");
            
            cfg.Properties.Add(Environment.MaxFetchDepth, "-1");
            switch (ConfigurationManager.AppSettings["DatabaseType"])
            {
                case "SqlServer2008":
                case "SqlServer2005":
                    cfg.Properties.Add(Environment.ConnectionDriver, "NHibernate.Driver.SqlClientDriver");
                    cfg.Properties.Add(Environment.Dialect, "Cms.Data.MsSql2008FullTextSearchDialect, Cms.Data");
                    cfg.Properties.Add(Environment.QuerySubstitutions, "true 1, false 0");
                    break;
                case "SqlServer2000":
                    cfg.Properties.Add(Environment.ConnectionDriver, "NHibernate.Driver.SqlClientDriver");
                    cfg.Properties.Add(Environment.Dialect, "NHibernate.Dialect.MsSql2000Dialect");
                    cfg.Properties.Add(Environment.QuerySubstitutions, "true 1, false 0");
                    break;
                case "MySql":
                    cfg.Properties.Add(Environment.ConnectionDriver, "NHibernate.Driver.MySqlDataDriver");
                    cfg.Properties.Add(Environment.Dialect, "NHibernate.Dialect.MySQL5Dialect");
                    cfg.Properties.Add(Environment.QuerySubstitutions, "true 1, false 0");
                    cfg.Properties.Add(Environment.Hbm2ddlKeyWords, "none");
                    break;
            }
            cfg.Properties.Add(Environment.ShowSql, ConfigurationManager.AppSettings["NHibernateShowSql"]);
            cfg.AddAssembly("Cms.Data"); // Assembly containing the mappings

            //cfg.AddDirectory(new DirectoryInfo(@"D:\Projects\Fredium\SourceCode\Cms.Web.UI\__System\CustomAdminPages"));
            
            if (ConfigurationManager.AppSettings["NHibernateCacheProvider"] == "SysCache")
            {
                cfg.Properties.Add(Environment.CacheProvider, "NHibernate.Caches.SysCache.SysCacheProvider, NHibernate.Caches.SysCache");
                cfg.Properties.Add(Environment.UseSecondLevelCache, "true");
                cfg.Properties.Add(Environment.UseQueryCache, "true");
            }
            
            Logging.LogInfo("Configure succeeded.");
            return cfg;
        }
    }
}